﻿using HslCommunication;
using HslCommunication.MQTT;
using JinYuan.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace JinYuan.Helper
{
    public class SendDateMQTT
    {
        /// <summary>
        /// 单类
        /// </summary>
        private static SendDateMQTT _instance;
        private static readonly object _lock = new object();
        public static SendDateMQTT Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_lock)
                    {
                        if (_instance == null)
                        {
                            _instance = new SendDateMQTT();
                        }
                    }

                }
                return _instance;
            }
        }

        private SendDateMQTT()
        {

            Connect(MQTTServerAddress, MQTTServerPort, "admin", "123456");
            //mqttClient.OnMqttMessageReceived += MqttClient_OnMqttMessageReceived; // 调用一次即可

        }

        /// <summary>
        /// 打印日志方法
        /// </summary>
        /// <param name="Message"></param>日志信息
        /// <param name="FileName"></param>文件夹名字
        public static void LogMessage(string Message, string FileName)
        {
            string filePath = FileName + "//" + DateTime.Now.ToString("yyyy-MM-dd"); // 日志文件存放路径，默认在debug目录下
            string filePath2 = FileName + "//" + DateTime.Now.ToString("yyyy-MM-dd") + "//Mylog.txt";//也可以加上时间
                                                                                                     //string file=DateTime.Now+"log.txt";
                                                                                                     //检查文件夹是否存在，否则新建
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            string logMessage = $"{DateTime.Now}: {Message}";//打印出现的时间
                                                             // 将消息写入日志文件
            using (StreamWriter writer = new StreamWriter(filePath2, true))
            {
                writer.WriteLine(logMessage);
            }
        }

        HslCommunication.MQTT.MqttClient mqttClient = null;
        //10.22.160.144
        public string MQTTServerAddress = "127.0.0.1";//"10.22.161.1";
        public int MQTTServerPort = 2883;
        public string ClientId = "602VIW01";
        //PPM主题
        public string Topic = "EVE/60J/TrackInOut/602VIW01";//进出站
        public string Topic1 = "EVE/60J/CTPCTQ/602VIW01";
        public string BU_id = "EVE8BU";
        public string District_id = "JM";
        public string Factory_id = "60J";
        public string Production_line_id = "MW-602";
        public string Work_center_id = "602VIE01";
        public string Device_name = "602VIW01";
        public string Action_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");




        /// <summary>
        /// 发送进出站数据
        /// </summary>
        /// <param name="topic"></param>
        /// <param name="IP"></param>
        /// <param name="Port"></param>
        /// <param name="cPQCPTDate"></param>
        public void EnterandExitSendMessge(int Station = 3)
        {
            try
            {
                ////if (mqttClient != null)
                ////    mqttClient.ConnectClose();
                if (!mqttClient.IsConnected)
                {
                    Connect(MQTTServerAddress, MQTTServerPort, "admin", "123456");
                }
                SubscribeMessage(Topic);
                //进站
                if (Station == 0)
                {
                    PublishMessage(Topic, EnterandExitMessge("0"));
                }
                //出站
                else if (Station == 1)
                {

                    PublishMessage(Topic, EnterandExitMessge("1"));
                }
            }
            catch (Exception err)
            {
                LoggerHelp.WriteError($"发送进出站数据错误，{err.Message}", err);
            }
        }
        /// <summary>
        /// 发送采集项数据
        /// </summary>
        /// <param name="topic"></param>
        /// <param name="IP"></param>
        /// <param name="Port"></param>
        /// <param name="cPQCPTDate"></param>
        public void CollectionSendMessge(CPQCPTDate cPQCPTDate)
        {
            try
            {
                if (!mqttClient.IsConnected)
                {
                    Connect(MQTTServerAddress, MQTTServerPort, "admin", "123456");
                }
                SubscribeMessage(Topic1);
                PublishMessage(Topic1, CollectionMessge(cPQCPTDate));
            }
            catch (Exception err)
            {
                LoggerHelp.WriteError($"发送采集项数据错误，{err.Message}", err);
            }
        }

        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="name"></param>
        /// <param name="pwd"></param>
        /// <param name="clientId"></param>
        public void Connect(string ip, int port, string name, string pwd, string clientId = "ClientId")
        {
            try
            {
                if (mqttClient != null)
                {
                    LoggerHelp.WriteMqtt("MQTT 服务器关闭失败");
                    mqttClient.ConnectClose();
                }

                mqttClient = new MqttClient(new MqttConnectionOptions()
                {
                    ClientId = clientId,
                    IpAddress = ip,
                    Port = port,
                    Credentials = new MqttCredential(name, pwd),   // 设置了用户名和密码
                });

                OperateResult connect = mqttClient.ConnectServer();
                if (connect.IsSuccess)
                {
                    LoggerHelp.WriteMqtt("MQTT 连接服务器成功");
                }
                else
                {
                    LoggerHelp.WriteMqtt("MQTT 无法连接到服务器");
                }
            }
            catch (Exception err)
            {
                LoggerHelp.WriteError($"MQTT 无法连接到服务器: {err.Message}");
            }


        }

        /// <summary>
        /// 发布信息
        /// </summary>
        /// <param name="topic"></param>
        public void PublishMessage(string topic, string Message)
        {
            try
            {
                OperateResult result = mqttClient.PublishMessage(new MqttApplicationMessage()
                {
                    Topic = topic,                                                      // 主题
                    QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce,     // 消息等级
                    Payload = Encoding.UTF8.GetBytes(Message),        // 数据
                    Retain = false,                                                   // 是否保留
                });
                if (result.IsSuccess)
                {
                    LoggerHelp.WriteMqtt($"发送消息到主题 [{topic}]: {Message}");
                }
                else
                {
                    LoggerHelp.WriteMqtt($"发送消息到主题 [{topic}] 失败: {result.Message}");
                }
            }
            catch (Exception err)
            {
                LoggerHelp.WriteError($"MQTT 无法连接到服务器: {err.Message}");
            }
        }

        /// <summary>
        /// 订阅主题
        /// </summary>
        /// <param name="topic"></param>
        public void SubscribeMessage(string Topic)
        {
            try
            {
                //mqttClient.OnMqttMessageReceived += MqttClient_OnMqttMessageReceived; // 调用一次即可
                OperateResult Result = mqttClient.SubscribeMessage(Topic);     // 订阅A的主题
                if (Result.IsSuccess)
                {
                    LoggerHelp.WriteMqtt($"订阅成功[{Topic}]");
                }
                else
                {
                    LoggerHelp.WriteMqtt($"订阅失败[{Topic}]");
                }
            }
            catch (Exception err)
            {
                LoggerHelp.WriteError($"订阅失败[{err.Message}]");
            }
        }

        private static void MqttClient_OnMqttMessageReceived(MqttClient client, MqttApplicationMessage message)
        {
            LoggerHelp.WriteMqtt($"收到服务器信息[{message.ToString()}]");
        }

        /// <summary>
        /// 拼接进出站json
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        public string EnterandExitMessge(string action)
        {
            string messgeJson = string.Empty;
            try
            {
                EnterandExit enterandExit = new EnterandExit()
                {
                    bu_id = BU_id,
                    district_id = District_id,
                    factory_id = Factory_id,
                    production_line_id = Production_line_id,
                    production_processes_id = "",
                    work_center_id = Work_center_id,
                    station_id = "",
                    device_name = Device_name,
                    action = action,
                    action_time = Action_time,
                };
                var messageJson = JsonConvert.SerializeObject(enterandExit, new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    Formatting = Formatting.None
                });
                messgeJson = messageJson;
            }
            catch (Exception ex)
            {
                LoggerHelp.WriteError($"方法：上传MQTTServer数据，上传失败: {ex.Message}", ex);
            }
            return messgeJson;
        }
        /// <summary>
        /// 拼接采集项数据
        /// </summary>
        /// <param name="cPQCPTDate"></param>
        /// <returns></returns>
        public string CollectionMessge(CPQCPTDate cPQCPTDate)
        {
            string messgejson = string.Empty;
            try
            {
                CollectionUpload enterandExit = new CollectionUpload()
                {
                    bu_id = BU_id,
                    district_id = District_id,
                    factory_id = Factory_id,
                    production_line_id = Production_line_id,
                    production_processes_id = "",
                    work_center_id = Work_center_id,
                    station_id = "",
                    device_name = Device_name,
                    taglist = new List<Collection>
    {
        new Collection
        {
            device_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
            collection_items = new Dictionary<string, string>
            {
                {"CTP_PreWeighing_Value",cPQCPTDate.CTP_PreWeighing_Value },
                {"CTP_Liquid_Retention_Value",cPQCPTDate.CTP_Liquid_Retention_Value },
                {"CTP_Filling_Value",cPQCPTDate.CTP_Filling_Value},
                {"CTP_Liquid_Loss_Value", cPQCPTDate.CTP_Liquid_Loss_Value},
                {"CTP_Helium_Filling_Value",cPQCPTDate.CTP_Helium_Filling_Value},
                {"CTP_Belljar_Vacuum_Value",cPQCPTDate.CTP_Belljar_Vacuum_Value},
                {"CTP_Belljar_Vacuum_Time",cPQCPTDate.CTP_Belljar_Vacuum_Time},
                {"CTP_Belljar_HighPressure_Value",cPQCPTDate.CTP_Belljar_HighPressure_Value},
                {"CTP_Belljar_HighPressure_Time",cPQCPTDate.CTP_Belljar_HighPressure_Time},
                {"CTP_Belljar_Cycles_Number",cPQCPTDate.CTP_Belljar_Cycles_Number},
                {"CTP_Pre_Helium_Value",cPQCPTDate.CTP_Pre_Helium_Value},
                {"CTP_Post_Helium_Value",cPQCPTDate.CTP_Post_Helium_Value},
                {"CTP_Flat_Pressure",cPQCPTDate.CTP_Flat_Pressure},
                {"CTP_Cell_Thickness_Pressure",cPQCPTDate.CTP_Cell_Thickness_Pressure},
                {"CTQ_PostWeighing_Value",cPQCPTDate.CTQ_PostWeighing_Value},
                {"CTQ_Cell_Thickness",cPQCPTDate.CTQ_Cell_Thickness},
                {"CTQ_Finalpress_Rubber_Height",cPQCPTDate.CTQ_Finalpress_Rubber_Height},
                {"CTP_PreInjection_Pressure",cPQCPTDate.CTP_PreInjection_Pressure},
                {"CTQ_Electrolyte_Inventory",cPQCPTDate.CTQ_Electrolyte_Inventory},
                {"CTP_PreNailing_Stroke",cPQCPTDate.CTP_PreNailing_Stroke},
                {"CTP_PreHelium_Vacuum_Pressure",cPQCPTDate.CTP_PreHelium_Vacuum_Pressure},
                {"CTP_FinalNailing_Stroke",cPQCPTDate.CTP_FinalNailing_Stroke},
                {"CTQ_Finalpress_Rubber_Thickness",cPQCPTDate.CTQ_Finalpress_Rubber_Thickness},
             }
        }
    }
                };
                var messageJson = JsonConvert.SerializeObject(enterandExit, new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    Formatting = Formatting.None
                });
                messgejson = messageJson;
            }
            catch (Exception ex)
            {
                LoggerHelp.WriteError($"生成Json数据失败: {ex.Message}", ex);
            }
            return messgejson;
        }
    }
}
